/******************************************************************************
 * Copyright (C) 2011 ShenZhen ComTop Information Technology Co.,Ltd
 * All Rights Reserved.
 * 本软件为深圳康拓普开发研制。未经本公司正式书面同意，其他任何个人、团体不得使用、
 * 复制、修改或发布本软件.
 *****************************************************************************/

package com.code.common.excel.officeexport.excel.process;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import com.code.common.excel.officeexport.excel.help.ExcelDefaultStyle;

/**
 * excel导出数据加载类
 * 
 * <pre></pre>
 * 
 * FIXME 重构点：字段是list但是里面装的东西要确定为一种类型
 * 
 * @author 李鹏
 * @since 1.0
 * @version 2012-11-09 李鹏 新建
 */
@SuppressWarnings("deprecation")
public class ExcelExportByExcel {
    
    /** 标题列表 */
    private final List<Object> titles = new ArrayList<Object>();
    
    /** 题头列表 */
    private final List<Object> heads = new ArrayList<Object>();
    
    /** 数据列表 */
    private final List<Object> data = new ArrayList<Object>();
    
    /** Excel对象 */
    private HSSFWorkbook workbook = null;
    
    /** 输出结果 */
    private final List<Object> result = new ArrayList<Object>();
    
    /** 记录分页标记 */
    private final Map<String, Object> breakMap = new HashMap<String, Object>();
    
    /** 日志管理类对象 */
    private static final Logger LOGGER = Logger.getLogger(ExcelExportByExcel.class);
    
    /**
     * 加载数据
     * 
     * @param excelExportConfig 配置信息
     * @param pageRequest request
     * @return 二维表 包含标题 题头 数据 分页数
     */
    @SuppressWarnings("unchecked")
    public List<Object> loadExcel(String strTemplateFile, List record) {
        try {
            this.loadFromExcel(strTemplateFile);
            this.loadData(0, record);
            result.add(this.titles);
            result.add(this.heads);
            result.add(this.data);
            result.add(this.breakMap);
        } catch (Exception e) {
            LOGGER.error("配置文件有误", e);
            return null;
        }
        
        // 判断加载数据方式，加载数据
        return result;
    }
    
    /**
     * 从Excel模板中读取样式
     * 
     * @param value 模板文件路径
     * @throws Exception 如果在运行过程当中出现错误就抛出异常Exception.
     * @throws IOException 如果在运行过程当中出现错误就抛出异常IOException.
     */
    private void loadFromExcel(String value) throws Exception, IOException {
        String strPath = ExportPrinter.TEMPLATES_DIRECTORY + value;
        FileInputStream objFileIn = null;
        try {
            objFileIn = new FileInputStream(strPath);
            POIFSFileSystem objPOIFile = new POIFSFileSystem(objFileIn);
            this.workbook = new HSSFWorkbook(objPOIFile);
        } catch (FileNotFoundException e) {
            LOGGER.error("模板文件没有找到", e);
            throw new Exception("模板文件没有找到", e);
        } catch (IOException e) {
            LOGGER.error("读取模板文件时发生错误", e);
            throw new Exception("读取模板文件时发生错误", e);
        } finally {
            if (objFileIn != null) {
                objFileIn.close();
            }
        }
    }
    
    /**
     * 加载数据
     * 
     * @param sheet xml文件分页对象
     * @param sequence xml文件中sheet对象对应顺序
     * @throws Exception 如果在运行过程当中出现错误就抛出异常Exception.
     */
    @SuppressWarnings("unchecked")
    private void loadData(int sequence, List lstData) {
        String strName = "sheet";
        String strBreakName = "list";
        Map<String, List> objMap = new HashMap<String, List>();
        objMap.put("list", lstData);
        breakMap.put(strName, strBreakName);
        this.data.add(sequence, objMap);
    }
    
    /**
     * @return 获取模板excel文件中模板workbook对象。
     */
    public HSSFWorkbook getWorkbook() {
        return workbook;
    }
    
    /**
     * @param objExcelExportLoader 用户Excel列顺序
     * @param listUserExcelData 用户Excel数据
     * @param writer writer
     * @throws Exception 
     */
    @SuppressWarnings("unchecked")
    public HSSFWorkbook createDynaExcel(List<? extends Object> lstRecord, Map objMap) throws Exception {
        // 创建模板工作表
        HSSFWorkbook objWorkbook = null;
        // 获取数据
        Map<String, Object> objMapUserExcelCol =
            (Map<String, Object>) objMap.get(ExcelExportAdapter.EXCEL_EXPORT_MAP_CHOOSE_TITLE);
        List<String> lstUserExcelColOrder =
            (List<String>) objMap.get(ExcelExportAdapter.EXCEL_EXPORT_LIST_CHOOSE_TITLE);
        // 创建工作簿实例
        objWorkbook = new HSSFWorkbook();
        
        // 获得工作表实例
        HSSFSheet objSheet = objWorkbook.createSheet();
        String strTitle = (String) objMap.get(ExcelExportAdapter.EXCEL_EXPORT_TITLE);
        writeTitle(objSheet, strTitle, lstUserExcelColOrder.size());// 设置标题
        HSSFRow objTemplateRow = objSheet.createRow(1);
        writeTHData(objTemplateRow, objMapUserExcelCol, lstUserExcelColOrder);// 设置题头
        
        for (int j = 0; j < lstRecord.size(); j++) {
            objTemplateRow = objSheet.createRow(j + 2);
            writeRowData(objTemplateRow, (Map<String, Object>) lstRecord.get(j), lstUserExcelColOrder);
        }
        return objWorkbook;
    }
    
    /**
     * 行数据填充处理
     * 
     * @param row 行
     * @param mapData 数据
     * @param lstUserExcelColOrder 用户Excel列顺序
     */
    public void writeRowData(HSSFRow row, Map<String, Object> mapData, List<String> lstUserExcelColOrder) {
        for (int i = 0; i < lstUserExcelColOrder.size(); i++) {
            String strKey = lstUserExcelColOrder.get(i);
            String strValue = String.valueOf(mapData.get(strKey));
            HSSFCell objTemplateCell = row.createCell(i);
            // 设置值 统一为String
            objTemplateCell.setCellValue(strValue);
        }
    }
    

    /**
     * 行数据填充处理
     * 
     * @param row 行
     * @param mapData 数据
     * @param lstUserExcelColOrder 用户Excel列顺序
     * @throws Exception 
     */
    public void writeTHData(HSSFRow row, Map<String, Object> mapData, List<String> lstUserExcelColOrder) throws Exception {
        HSSFCellStyle objCellStyle = ExcelDefaultStyle.getHeadStyle(row.getSheet().getWorkbook());
        for (int i = 0; i < lstUserExcelColOrder.size(); i++) {
            String strKey = lstUserExcelColOrder.get(i);
            String strValue = String.valueOf(mapData.get(strKey));
            HSSFCell objTemplateCell = row.createCell(i);
            objTemplateCell.setCellStyle(objCellStyle);
            // 设置值 统一为String
            objTemplateCell.setCellValue(strValue);
        }
    }
    
    /**
     * 行数据填充处理
     * 
     * @param row 行
     * @param mapData 数据
     * @param lstUserExcelColOrder 用户Excel列顺序
     * @throws Exception 
     */
    public void writeTitle(HSSFSheet sheet, String value, int size) throws Exception {
        HSSFRow objTemplateTitle = sheet.createRow(0);
        HSSFCellStyle objCellStyle = ExcelDefaultStyle.getTitleStyle(sheet.getWorkbook());
        for (int i = 0; i < size; i++) {
            HSSFCell objCell = objTemplateTitle.createCell(i);
            objCell.setCellStyle(objCellStyle);
            sheet.setColumnWidth(i, 6000);
        }
        objTemplateTitle.getCell(0).setCellValue(value);
        objTemplateTitle.setHeight((short) 600);// 设置高度
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, size - 1));
    }
    
  
    
}
